# -*- coding: utf-8 -*-

import pystore.core.framework.os2 as os2


class _NotBindingException(Exception):
    def __init__(self,projectName):
        self.projectName = projectName
        
    def __str__(self):
        return u'project(%s) is not binding disk path' % (self.projectName) 
 
class NodeStatus(object):
    """
    节点状态，根据节点在本地和客户端的存在情况或日期先后等条件分为以下几种:
        常量引用          名称              符号
       ----------------------------------------------------
        NOT_BINDING  'notBinding'     '?' 
        NOT_EXISTS   'notExists'      '!'
        ADD          'add'            '+'
        NEW          'new'            '>'
        LACK         'lack'           '-'
        OLD          'old'            '<'
        CONFLICT     'conflict'       '*'
        NORMAL       'normal'         ''
        
     例：
        status=node_status.NOT_BINDING
    可以通过node_status模块获取表中常量的引用,返回的引用即是NodeStatus类型
    """
    def __init__(self,name,symbol):
        self.__name=name
        self.__symbol=symbol
        
    def name(self):
        """
        name() -> str
        
         返回状态的名称        
        """
        return self.__name
    
    def symbol(self):
        """
        symbol() -> str
        
         返回状态的示意符号        
        """
        return self.__symbol
    
    def _commitFile(self,fileNode):
        pass
    
    def _commitDir(self,dirNode):
        pass
    
    def _updateFile(self,fileNode):
        pass

    def _updateDir(self,dirNode):
        pass
    
    def __str__(self):
        return u'<Status:%s(%s)>' % (self.__symbol,self.__name)
    
    def __repr__(self):
        return str(self)
 
class _NotBindingStatus(NodeStatus):
    def _commitFile(self,fileNode):
        raise _NotBindingException(fileNode.project().name())
    
    def _commitDir(self,dirNode):
        raise _NotBindingException(dirNode.project().name())
        
    def _updateFile(self,fileNode):
        raise _NotBindingException(fileNode.project().name())
        
    def _updateDir(self,dirNode):
        raise _NotBindingException(dirNode.project().name())
    
class _NotExistStatus(NodeStatus):
    pass

class _ConflictStatus(NodeStatus):
    pass

class _AddStatus(NodeStatus):
    def _commitFile(self,fileNode):
        fileNode._remoteService().uploadFile(fileNode.localPath(),fileNode.remotePath())

    def _commitDir(self,dirNode):
        dirNode._remoteService().makedirs(dirNode.remotePath())

    def _updateFile(self,fileNode):
        os2.removeFile(fileNode.localPath())
        
    def _updateDir(self,dirNode):
        os2.rmdir(dirNode.localPath())
            
class _LackStatus(NodeStatus):
    def _commitFile(self,fileNode):
        fileNode._remoteService().removeFile(fileNode.remotePath())
        
    def _commitDir(self,dirNode):
        dirNode._remoteService().rmdir(dirNode.remotePath())
        
    def _updateFile(self,fileNode):
        fileNode._remoteService().downloadFile(fileNode.localPath(),fileNode.remotePath())
        
    def _updateDir(self,dirNode):
        os2.makedirs(dirNode.localPath())
  
class _NewStatus(NodeStatus):
    def _commitFile(self,fileNode):
        ADD._commitFile(fileNode)

class _OldStatus(NodeStatus):
    def _updateFile(self,fileNode):
        LACK._updateFile(fileNode)

class _NormalStatus(NodeStatus):
    pass

# NodeStatus instance
NOT_BINDING  =_NotBindingStatus('notBinding','?') 
NOT_EXISTS   =_NotExistStatus(    'notExists','!')
ADD          =_AddStatus(          'add'     ,'+')
NEW          =_NewStatus(          'new'     ,'>')
LACK         =_LackStatus(         'lack'    ,'-')
OLD          =_OldStatus(          'old'     ,'<')
CONFLICT     =_ConflictStatus(     'conflict','*')
NORMAL       =_NormalStatus(       'normal'  ,'')
